﻿#include "ssBO.h"

namespace StarSeeker
{
//BO
ssBO::ssBO()
{
	m_handle = 0;
	m_usage = SS_VBO_STATIC;
	m_target = GL_ARRAY_BUFFER;
}
ssBO::~ssBO()
{
	Delete();
}
bool ssBO::Create( u32 usage )
{
	if (m_handle==0)
	{
		m_usage = usage;
		glGenBuffers(1, &m_handle);
	}
	return m_handle!=0;
}
void ssBO::Delete()
{
	if (m_handle!=0)
	{
		glDeleteBuffers(1, &m_handle);
		m_handle = 0;
	}
}
void ssBO::Use()
{
	if (m_handle!=0)
		glBindBuffer(m_target, m_handle);
}

void ssBO::Nonuse()
{
	glBindBuffer(m_target, 0);
}

void ssBO::InitData(const void* data, u32 len)
{
	if (m_handle!=0 && data)
		glBufferData(m_target, len, data, m_usage);
}
#ifndef SS_USE_GLES2
ssfloat* ssBO::BeginMapping(u32 rw)
{
	if (m_handle!=0)
	{
		glBufferData(m_target, 0, 0, m_usage);
		return (ssfloat*)glMapBuffer(m_target, rw);
	}
	return 0;
}
void ssBO::EndMapping()
{
	if (m_handle!=0)
	{
		glUnmapBuffer(m_target);
	}
}
#endif
void ssBO::Update( u32 offset, u32 size, const void* data )
{
	glBufferSubData(m_target, offset, size, data);
}
bool ssBO::IsValid()
{
	return m_handle != 0;
}

//VBO
ssVBO::ssVBO()
{
	m_target = GL_ARRAY_BUFFER;
}
void ssVBO::Nonuse()
{
	glBindBuffer(GL_ARRAY_BUFFER, 0);
}

//IBO
ssIBO::ssIBO()
{
	m_target = GL_ELEMENT_ARRAY_BUFFER;
}
void ssIBO::Nonuse() 
{
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}

#ifndef SS_USE_GLES2
//PBO
ssPBO::ssPBO()
{
	m_target = GL_PIXEL_UNPACK_BUFFER;
}
void ssPBO::SetTarget(u32 target)
{
	//Target标志指定PBO的两种不同的操作：GL_PIXEL_PACK_BUFFER_ARB 传递像素数据到PBO中。或GL_PIXEL_UNPACK_BUFFER_ARB 从PBO中传回数据。
	//例如，glReadPixels()和glGetTexImage()是"pack"像素操作， glDrawPixels(), glTexImage2D() ，glTexSubImage2D() 是"unpack" 操作。
	//当一个PBO的标志为GL_PIXEL_PACK_BUFFER_ARB, glReadPixels()从OpenGL的一个帧缓冲区读取数亿，并将数据写(pack)入PBO中。
	//当一个PBO的标志为GL_PIXEL_UNPACK_BUFFER_ARB时, glDrawPixels()从PBO读取(unpack)像素数据并复制到OpenGL帧缓冲区中。
	m_target = target;
}
void ssPBO::Nonuse()
{
	glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
	//glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
}
#endif

}
